package com.danton.user.controller;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.crypto.hash.Sha1Hash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.danton.auth.token.LoginToken;
import com.danton.common.Config;
import com.danton.common.bean.CommonResponse;
import com.danton.common.exception.UserAlreadyExistException;
import com.danton.common.utils.DateUtils;
import com.danton.common.utils.StringUtils;
import com.danton.framework.BaseController;
import com.danton.model.BsAdminModel;
import com.danton.model.BsAdminRoleModel;
import com.danton.model.BsPermissionModel;
import com.danton.model.BsRoleModel;
import com.danton.user.service.RoleService;
import com.danton.user.service.UserService;
import com.danton.user.service.impl.RoleServiceImpl;
import com.danton.user.service.impl.UserServiceImpl;
import com.danton.user.validator.RegisterValidator;
import com.jfinal.aop.Before;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Page;

public class UserController extends BaseController {
	protected static final Logger logger = LoggerFactory.getLogger(UserController.class);
	private UserService userService = enhance(UserServiceImpl.class);// 支持事务处理
	private RoleService roleService = enhance(RoleServiceImpl.class);// 支持事务处理

	public void list() {
		int pn = getParaToInt("page_number", page_number);
		int ps = getParaToInt("page_size", page_size);
		Page<BsAdminModel> page = userService.listUser(pn, ps);
		List<BsAdminModel> list = page.getList();
		for (BsAdminModel bsadminModel : list) {
			int admin_id = bsadminModel.get("id");
			List<BsRoleModel> roles = userService.findRoleNameByUserID(admin_id);
			String role_name = "";
			for (BsRoleModel brole : roles) {
				role_name = role_name + brole.get("role_name") + ",";
			}
			bsadminModel.put("role_name", role_name);
		}

		CommonResponse respones = CommonResponse.buildResponse();
		respones.getBody().put("page", page);
		renderJson(respones);
	}

	public void search() {
		int pn = getParaToInt("page_number", page_number);
		int ps = getParaToInt("page_size", page_size);
		String kw = getPara("kw");
		Page<BsAdminModel> page = userService.searchUser(pn, ps, kw);
		List<BsAdminModel> list = page.getList();
		for (BsAdminModel bsadminModel : list) {
			int admin_id = bsadminModel.get("id");
			List<BsRoleModel> roles = userService.findRoleNameByUserID(admin_id);
			String role_name = "";
			for (BsRoleModel brole : roles) {
				role_name = role_name + brole.get("role_name") + ",";
			}
			bsadminModel.put("role_name", role_name);
		}
		CommonResponse respones = CommonResponse.buildResponse();
		respones.getBody().put("page", page);
		renderJson(respones);
	}

	/**
	 * 新增
	 */
	@Before(RegisterValidator.class)
	public void register() {
		String user_name = getPara("user_name");
		String password = getPara("password");// 此处密码已经做过摘要处理
		String ip_address = getPara("ip_address", "127.0.0.1");
		String access_key_id = getPara("access_key_id");
		String access_key_secret = getPara("access_key_secret");
		String role_code = getPara("role_code");
		String nike_name = getPara("nike_name");
		String identity_code = getPara("identity_code");
		String mobile_phone = getPara("mobile_phone");
		String email = getPara("email");
		String department = getPara("department");
		String telphone = getPara("telphone");
		String remark = getPara("remark");
		//String user_Id = getPara("user_Id"); // 当前登录用户的id
		String powers = getPara("powers");// 角色ids
		String user_id=null;
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		if (StringUtils.isNotEmpty(session_id)) {
			Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory(
					"classpath:shiro.ini");
			// 2、得到SecurityManager实例 并绑定给SecurityUtils
			org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
			SecurityUtils.setSecurityManager(securityManager);

			// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
			// Subject subject = SecurityUtils.getSubject();
			Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
			if (subject.isAuthenticated()) {
				BsAdminModel adminModel = (BsAdminModel) subject.getPrincipal();
				if (adminModel != null) {
					user_id = String.valueOf(adminModel.getInt("id"));
				}
			}
		}else{
			renderJson(CommonResponse.buildResponse(900, "session为空！"));
			return;
		}		
				
		Properties pro = PropKit.use(Config.accessFileName).getProperties();
		if (pro == null) {
			renderJson(CommonResponse.buildResponse(600, "内部错误"));
			return;
		} else {
			String local_key_secret = pro.getProperty(access_key_id);
			if (local_key_secret == null || !local_key_secret.equals(access_key_secret)) {
				renderJson(CommonResponse.buildResponse(601, "access_key 错误"));
				return;
			}
		}

		if (StringUtils.isEmpty(user_id)) {
			renderJson(CommonResponse.buildResponse(801, "请登录Rosary系统注册"));
			return;
		} else {
			boolean flag = false;
			List<BsRoleModel> rolelist = userService.findRolesByUserID(Integer.parseInt(user_id));
			if (rolelist != null && rolelist.size() > 0) {
				// 设定为只有权限管理员才可以注册用户
				for (BsRoleModel rm : rolelist) {
					String roleid = String.valueOf(rm.getInt("id"));
					if ("11".equals(roleid)) {
						flag = true;
					}
				}
			}
			if (flag) {
				BsAdminModel returnadminModel = new BsAdminModel();
				String admin_id = null;
				try {
					BsAdminModel adminModel = new BsAdminModel();
					adminModel.set("user_name", user_name).set("password", password).set("ip_address", ip_address)
							.set("source", access_key_id).set("nike_name", nike_name)
							.set("identity_code", identity_code).set("mobile_phone", mobile_phone).set("email", email)
							.set("department", department).set("telephone", telphone).set("remark", remark);
					userService.register(adminModel, role_code, access_key_id);
					returnadminModel = userService.findByUserName(user_name);
					if (returnadminModel != null) {
						admin_id = String.valueOf(returnadminModel.get("id")); // 返回新增的id
					}
					// 新增用户关联角色
					List<BsAdminRoleModel> armlist = new ArrayList<BsAdminRoleModel>();
					if (StringUtils.isNotEmpty(powers)) {
						String[] power_array = powers.split(",");
						for (String power : power_array) {
							if (StringUtils.isNotEmpty(power)) {
								BsAdminRoleModel arm = new BsAdminRoleModel();
								arm.set("admin_id", admin_id).set("role_id", power);
								armlist.add(arm);
							}
						}
					}
					userService.AddAdminRole(armlist);

				} catch (UserAlreadyExistException e) {
					renderJson(CommonResponse.buildResponse(602, "用户已经存在"));
					return;
				}

				CommonResponse responeStatus = CommonResponse.buildResponse();
				responeStatus.getBody().put("user_name", user_name);
				responeStatus.getBody().put("user_id", admin_id);
				renderJson(responeStatus);
			} else {
				renderJson(CommonResponse.buildResponse(802, "没有权限管理员权限"));
				return;
			}
		}
	}

	public void edit() {
		int user_id = getParaToInt("user_id");
		String nike_name = getPara("nike_name");
		String identity_code = getPara("identity_code");
		String mobile_phone = getPara("mobile_phone");
		String email = getPara("email");
		String department = getPara("department");
		String telphone = getPara("telphone");
		String remark = getPara("remark");
		String powers = getPara("powers");// 角色ids
		BsAdminModel adminModel = new BsAdminModel();
		adminModel.set("id", user_id).set("nike_name", nike_name).set("identity_code", identity_code)
				.set("mobile_phone", mobile_phone).set("email", email).set("department", department)
				.set("telephone", telphone).set("remark", remark);
		userService.edit(adminModel);
		// 新增用户关联角色
		String user_ids = user_id + "";
		roleService.deleteRoleAdminByUserId(user_ids.trim()); // 删除原有的用户关联角色
		List<BsAdminRoleModel> armlist = new ArrayList<BsAdminRoleModel>();
		if (StringUtils.isNotEmpty(powers)) {
			String[] power_array = powers.split(",");
			for (String power : power_array) {
				if (StringUtils.isNotEmpty(power)) {
					BsAdminRoleModel arm = new BsAdminRoleModel();
					arm.set("admin_id", user_id).set("role_id", power);
					armlist.add(arm);
				}
			}
		}
		userService.AddAdminRole(armlist);

		renderJson(CommonResponse.buildResponse());
	}

	public void lock() {
		int user_id = getParaToInt("user_id");
		BsAdminModel adminModel = new BsAdminModel();
		adminModel.set("id", user_id).set("status", 1);
		userService.edit(adminModel);
		renderJson(CommonResponse.buildResponse());
	}

	public void unlock() {
		int user_id = getParaToInt("user_id");
		BsAdminModel adminModel = new BsAdminModel();
		adminModel.set("id", user_id).set("status", 0);
		userService.edit(adminModel);
		renderJson(CommonResponse.buildResponse());
	}

	/**
	 * 登陆
	 */
	public void login() {
		CommonResponse responeStatus = CommonResponse.buildResponse();

		String user_name = getPara("user_name");
		String password = getPara("password");
		String access_key_id = getPara("access_key_id");
		String sessionID = "";
		int user_id = -1;

		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();

		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		Subject subject = SecurityUtils.getSubject();
		String login_time = "2016-01-01 01:01:01"; // 上次登录时间
		String nike_name = "";
		String rolename = ""; // 角色
		String department = ""; // 部门
		if (subject.isAuthenticated()) {
			// Session session = subject.getSession();
			// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd mm:ss");
			// Map<String,Object> result = new HashMap<>();
			// result.put("login_time",
			// sdf.format(session.getStartTimestamp()));
			// result.put("lastAccess_time",
			// sdf.format(session.getLastAccessTime()));
			sessionID = (String) subject.getSession().getId();
		} else {
			LoginToken token = new LoginToken(user_name, password, access_key_id);
			token.setHost(access_key_id);
			try {
				// 4、登录，即身份验证
				subject.login(token);
				sessionID = (String) subject.getSession().getId();
				BsAdminModel adminModel = (BsAdminModel) subject.getPrincipal();
				user_id = adminModel.getInt("id");
				if (StringUtils.isNotEmpty(adminModel.getStr("department"))) {
					department = adminModel.getStr("department");
				}

				Timestamp timestamp = adminModel.getTimestamp("login_time");
				if (timestamp != null) {
					login_time = DateUtils.getTime(timestamp.getTime() / 1000);
				}
				String nickname = adminModel.getStr("nike_name");
				if (StringUtils.isNotEmpty(nickname)) {
					nike_name = nickname;
				}
				// 验证成功,保存登录时间
				adminModel.set("login_time", DateUtils.getNowTime());
				userService.UpdateAdmin(adminModel);
			} catch (UnknownAccountException e) {
				logger.error(e.getMessage());
				// 5、身份验证失败
				responeStatus = CommonResponse.buildResponse(610, e.getMessage());
				renderJson(responeStatus);
				return;
			} catch (IncorrectCredentialsException e) {
				logger.error(e.getMessage());
				// 5、身份验证失败
				responeStatus = CommonResponse.buildResponse(611, e.getMessage());
				renderJson(responeStatus);
				return;
			} catch (AuthenticationException e) {
				logger.error(e.getMessage());
				responeStatus = CommonResponse.buildResponse(612, e.getMessage());
				renderJson(responeStatus);
				return;
			}
			// BsAdminModel adminModel = userService.findByUserName(user_name);
		}
		// 用户所有权限

		List<BsRoleModel> rolelist = userService.findRoleNameByUserID(user_id);
		if (rolelist != null && rolelist.size() > 0) {
			for (BsRoleModel brm : rolelist) {
				String name = brm.getStr("role_name");
				if (StringUtils.isNotEmpty(name)) {
					rolename = rolename + name + ",";
				}
			}
		}
		List<BsPermissionModel> permissionlist = userService.findPermissionsByUserID(user_id);

		// 返回sessionID及用户名,用户ID
		responeStatus.getBody().put("OBSIDIAN_SESSION", sessionID);
		responeStatus.getBody().put("department", department);
		responeStatus.getBody().put("user_name", user_name);
		responeStatus.getBody().put("nike_name", nike_name);
		responeStatus.getBody().put("login_time", login_time);
		responeStatus.getBody().put("rolename", rolename);
		responeStatus.getBody().put("list", permissionlist);
		responeStatus.getBody().put("user_id", String.valueOf(user_id));
		renderJson(responeStatus);
		logger.debug("=======session_id========:" + sessionID);
	}

	/**
	 * 注销登陆
	 */
	public void logout() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		// Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if (subject.isAuthenticated() || subject.isRemembered()) {
			subject.logout();
		}
		renderJson(responeStatus);
	}

	/**
	 * 查询权限
	 */
	public void checkSessionId() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		if (StringUtils.isNotEmpty(session_id)) {
			Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory(
					"classpath:shiro.ini");

			// 2、得到SecurityManager实例 并绑定给SecurityUtils
			org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
			SecurityUtils.setSecurityManager(securityManager);

			// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
			// Subject subject = SecurityUtils.getSubject();
			Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
			if (subject.isAuthenticated()) {
				BsAdminModel adminModel = (BsAdminModel) subject.getPrincipal();
				int user_id = 0;
				String user_name = "";
				String nike_name = "";
				String rolename = "";
				if (adminModel != null) {
					user_id = adminModel.getInt("id");
					user_name = adminModel.getStr("user_name");
				}
				List<BsRoleModel> rolelist = userService.findRolesByUserID(user_id);
				if (rolelist != null && rolelist.size() > 0) {
					for (BsRoleModel brm : rolelist) {
						String name = brm.getStr("role_name");
						if (StringUtils.isNotEmpty(name)) {
							rolename = rolename + name + ",";
						}
					}
				}
				List<BsPermissionModel> permissionlist = userService.findPermissionsByUserID(user_id);

				responeStatus.getBody().put("OBSIDIAN_SESSION", session_id);
				responeStatus.getBody().put("user_id", user_id);
				responeStatus.getBody().put("user_name", user_name);
				responeStatus.getBody().put("nike_name", nike_name);
				responeStatus.getBody().put("rolename", rolename);
				responeStatus.getBody().put("list", permissionlist);
				renderJson(responeStatus);
				// return;
			} else {
				responeStatus = CommonResponse.buildResponse(621, "请重新登录");
			}
		} else {
			responeStatus = CommonResponse.buildResponse(444, "session_id为空");

		}
		logger.debug("=======session_id========:" + session_id);
		renderJson(responeStatus);
	}

	/**
	 * 查询权限
	 */
	public void checkPermission() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		String permission = getPara("permission");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		// Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if (subject.isAuthenticated()) {
			if (subject.isPermitted(permission)) {
				/*
				 * BsAdminModel adminModel =
				 * (BsAdminModel)subject.getPrincipal();
				 * responeStatus.getBody().put("admin", adminModel);
				 */
				renderJson(responeStatus);
				return;
			} else {
				responeStatus = CommonResponse.buildResponse(620, "没有权限");
			}
		} else {
			responeStatus = CommonResponse.buildResponse(621, "请重新登录");
		}
		renderJson(responeStatus);
	}

	public void listRoles() {
		CommonResponse responeStatus = CommonResponse.buildResponse();
		String session_id = getRequest().getHeader("OBSIDIAN_SESSION");
		Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

		// 2、得到SecurityManager实例 并绑定给SecurityUtils
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		// 3、得到Subject及创建用户名/密码身份验证Token（即用户身份/凭证）
		// Subject subject = SecurityUtils.getSubject();
		Subject subject = new Subject.Builder().sessionId(session_id).buildSubject();
		if (subject.isAuthenticated()) {
			BsAdminModel adminModel = (BsAdminModel) subject.getPrincipal(); // 得到用户名
			List<BsRoleModel> roles = userService.findRolesByUserID(adminModel.getInt("id"));
			List<String> roleCode = new ArrayList<String>();
			for (BsRoleModel bsRoleModel : roles) {
				roleCode.add(bsRoleModel.getStr("code"));
			}
			responeStatus.getBody().put("roles", roleCode);
		} else {
			responeStatus = CommonResponse.buildResponse(621, "请重新登录");
		}
		renderJson(responeStatus);
	}

	/*
	 * 查询所有角色
	 */
	public void listAllRoles() {
		List<BsRoleModel> rolelist = roleService.listAllRoles();
		CommonResponse respones = CommonResponse.buildResponse();
		respones.getBody().put("list", rolelist);
		renderJson(respones);
	}

	/*
	 * 查询用户已关联角色
	 */
	public void listUserRoles() {
		int user_id = getParaToInt("user_id");
		List<BsRoleModel> rolelist = roleService.listUserRoles(user_id);
		CommonResponse respones = CommonResponse.buildResponse();
		respones.getBody().put("list", rolelist);
		renderJson(respones);
	}

	public void info() {
		int user_id = getParaToInt("user_id");
		BsAdminModel adminModel = userService.findByUserID(user_id);
		CommonResponse responeStatus = CommonResponse.buildResponse();
		responeStatus.getBody().put("user_name", adminModel.get("user_name"));
		renderJson(responeStatus);
	}

	/*
	 * 重置密码
	 */
	public void resetPassword() {
		int user_id = getParaToInt("user_id");
		userService.resetPassword(user_id);
		renderJson(CommonResponse.buildResponse());
	}

	/*
	 * 修改密码
	 */
	public void updatePassword() {
		int user_id = getParaToInt("user_id");
		String oldpassword = getPara("oldpassword");
		String newpassword = getPara("newpassword");
		BsAdminModel admin = userService.findByUserID(user_id);
		String ip_address = admin.get("ip_address");
		String sha1 = new Sha1Hash(oldpassword, ip_address).toString();
		CommonResponse respones = CommonResponse.buildResponse();
		if (!sha1.equals(admin.get("password"))) {
			respones.setErrno(1);
			respones.setMessage("原密码错误");
			// throw new IncorrectCredentialsException("密码错误"); // 密码错误
		} else {
			admin.set("password", new Sha1Hash(newpassword, ip_address).toString());// 新密码
			boolean flag = userService.UpdateAdmin(admin);
			if (flag) {
				respones.setErrno(0);
				respones.setMessage("密码修改成功");
			} else {
				respones.setErrno(2);
				respones.setMessage("密码修改失败");
			}
		}
		renderJson(respones);
	}
}
